package org.wattdepot.gdata.kukuicup.updater.energygoalgame;

import java.util.Timer;
import java.util.TimerTask;
import org.wattdepot.gdata.kukuicup.service.GDataService;
import org.wattdepot.gdata.kukuicup.service.WattDepotService;
import org.wattdepot.gdata.kukuicup.updater.Updater;

/**
 * Implements the EnergyGoalGameBetaEval Updater, which creates individual timer tasks for
 * each source that must run once every 6 minutes and updates the spreadsheet with simulated
 * actual and goal energy consumption values for that source for the day so far. 
 * @author Philip Johnson
 */
public class EnergyGoalGameBetaEvalUpdater extends Updater {
  
  /** The property in the kukuicup.gdata.properties file indicating how often to update. */
  private String updateIntervalProperty = "energy.goal.game.beta.eval.update.interval";
  /** The default interval for the updates if not otherwise specified. */
  private int defaultUpdateInterval = 6;
  
  /** How much energy reduction is currently required to get out of red. */
  private String goalReductionProperty = "energy.goal.game.beta.eval.goal.reduction.goal";
  /** If not specified, what goal reduction to use by default. */
  private int defaultGoalReduction = 10;

  /** How much energy reduction is currently required to get out of yellow. */
  private String goalWarningProperty = "energy.goal.game.beta.eval.goal.warning.goal";
  /** If not specified, what warning reduction to use by default. */
  private int defaultWarningReduction = 7;

  /** Where the user data file is located. */
  private String userDataFileNameProperty = "energy.goal.game.beta.eval.data.file";

  
  /**
   * Creates this updater, initializing the various services. 
   * @param wattDepotService The wattdepot service. 
   * @param gdataService The gdata service.
   * @throws Exception If problems occur initializing these services.  
   */
  public EnergyGoalGameBetaEvalUpdater(WattDepotService wattDepotService, GDataService gdataService)
  throws Exception {
    super("EnergyGoalGameBetaEval", wattDepotService, gdataService);
  }


  /**
   * This task generates a separate TimerTask for each source in the spreadsheet. 
   * Each TimerTask runs every N minute, gets the current consumption and goal values for
   * its source, then writes out that data value to the spreadsheet.
   * N depends upon the energy.goal.game.update.interval property.
   */
  @Override
  public void run() {
    // Get the update interval for getting the current power.
    int updateInterval = this.wattDepotService.getProperties()
    .getIntegerProperty(updateIntervalProperty, defaultUpdateInterval);
    System.out.format("Updating EnergyGoalGameBetaEval spreadsheet at %s min intervals%n", 
        updateInterval);

    // Get the goal reduction
    int goalReduction = this.wattDepotService.getProperties()
    .getIntegerProperty(goalReductionProperty, defaultGoalReduction);
    System.out.format("EnergyGoalGameBetaEval reduction target is: %s%n", goalReduction);
    
    // Get the warning reduction
    int warningReduction = this.wattDepotService.getProperties()
    .getIntegerProperty(goalWarningProperty, defaultWarningReduction);
    System.out.format("EnergyGoalGameBetaEval warning target is: %s%n", warningReduction);

    // Get the user data file name.
    String userDataFileName = this.wattDepotService.getProperties()
    .getRequiredProperty(this.userDataFileNameProperty);
    
    // We space out these task initiation to avoid overloading WattDepot. 
    int delay = 0;

    for (String sourceName : sourceNames) {
      Timer timer = new Timer();
      TimerTask task = new EnergyGoalGameBetaEvalTask(wattDepotService, gdataService, 
          spreadsheetURL, sourceName, isVirtual(sourceName), getRow(sourceName), goalReduction,
          warningReduction, userDataFileName);
      // Convert update interval to milliseconds. 
      int updateIntervalMillis = 60 * 1000 * updateInterval;
      timer.schedule(task, delay, updateIntervalMillis);
      // stagger task execution by 10 seconds so they don't hit the WattDepot all at once.  
      delay += 1000 * 10;
      timers.add(timer);
    }
  }


}
